--------------------------- Class SmartBounce ---------------------------
format debug "--  Compiling SmartBounce Class . . .\n" undefined undefined

class SmartBounce(TwoDController)
inst vars
	walls, friction, escapeVelocity
end

function checkWall obj sb ->
(
 	if not (isAKindof obj Projectile) do (
 		print "Not a Projectile" --debug
 		return "Not a Projectile"
 	)
	local sceneRect := sb.walls
	local friction := sb.friction
	local myRect := obj.globalBoundary
	local x1 := myRect.x1
	local x2 := myRect.x2
	local y1 := myRect.y1
	local y2 := myRect.y2
	local objVelocity := obj.velocity
	local ovy := objVelocity.y
	local ovx := objVelocity.x
	if ovy = 0 and ovx = 0 do return OK -- orb is at rest
	local obbox := obj.bbox
	local elast := obj.elasticity
	local whichWall := undefined
	local mySpace := sb.space
	local myPortals := mySpace.portals
	
	if (x1 < sceneRect.x1) do (
		obj.x := sceneRect.x1 - obbox.x1
		ovx := abs(ovx * elast)
		whichWall := @west
	)

	if (y1 < sceneRect.y1) do (
		obj.y := sceneRect.y1 - obbox.y1
		ovy := abs(ovy * elast)
		whichWall := @north
	)

	if (x2 > sceneRect.x2) do (
		obj.x := sceneRect.x2 - (obj.width + obbox.x1)
		ovx := -(ovx * elast)
		whichWall := @east
	)

	if (y2 > sceneRect.y2) do (
		obj.y := sceneRect.y2 - (obj.height + obbox.y1)
		ovy := -(ovy * elast)
		whichWall := @south
	)
	
	if whichWall <> undefined do (
		local toScene := myPortals[whichWall]
		local amplitude := (abs(ovx) + abs(ovy))
		if toScene = undefined then (
			makeSound obj #(@wall,amplitude)
			objVelocity.x := ovx * friction
			objVelocity.y := ovy * friction
		) else (
			if amplitude > sb.escapeVelocity then (
--				format debug "Exiting to the %*...\n" (whichWall as string) @unadorned
				local newScene := showScene mySpace.myStage toScene
				case whichWall of
					@east: obj.x := sceneRect.x1 - obbox.x1
					@north: obj.y := sceneRect.y2 - (obj.height + obbox.y1)
					@west: obj.x := sceneRect.x2 - (obj.width + obbox.x1)
					@south:obj.y := sceneRect.y1 - obbox.y1
				end
--				format debug "Putting orb in %*\n" newScene @normal
				if obj.size = 2 do (
					stop obj[1]
					pop obj
				)
				prepend newScene obj
				hook obj
			) else (
				makeSound obj #(@portal,amplitude)
				objVelocity.x := ovx * friction
				objVelocity.y := ovy * friction
			)
		)
	)
	return OK
)

method afterInit self {Class SmartBounce} #rest args->
(
	emptyOut self.protocols
	append self.protocols Projectile
	self.walls := self.space.bbox
	self.friction := 0.95
	self.escapeVelocity := 10
	apply nextMethod self args
)
method tickle self {Class SmartBounce} myClock->
(
--	nextMethod self myClock
	forEach self checkWall self
)
--------------------------- End SmartBounce ---------------------------
#(SmartBounce,#("escapeVelocity"),#())
